import hashlib
from typing import Annotated

from fastapi import APIRouter, Header, Depends

from app_v2.AsyncDataBase import get_async_db_cursor
from app_v2.bili_api.api import ApiSession
from app_v2.error import CookieError
from app_v2.model import Account
from app_v2.routes.proxy import code_cache

router = APIRouter(tags=["account"])


@router.post("/login")
async def login(account: Account, cursor=Depends(get_async_db_cursor)):
    username = account.username
    password = account.password
    # MD5 加密
    password_hash = hashlib.md5(password.encode()).hexdigest()
    await cursor.execute("select uid, cookies from bwdap_users where username = %s and password = %s",
                         [username, password_hash])
    result = await cursor.fetchone()
    if not result:
        return {
            "code": 401,
            "message": "用户不存在或密码错误"
        }
    # update token
    if account.qrcode_key and account.qrcode_key != "" and (cookie := code_cache[account.qrcode_key]):
        await cursor.execute("UPDATE bwdap_users SET cookies = %s where uid = %s", [cookie, result["uid"]])
        return {
            "code": 200,
            "uid": result["uid"],
            "cookies": cookie
        }
    # check token
    await check_token(result["cookies"])
    return {
        "code": 200,
        "uid": result["uid"],
        "cookies": result["cookies"]
    }


@router.post("/register")
async def register(account: Account, cursor=Depends(get_async_db_cursor)):
    if not account.qrcode_key or not (cache_cookie := code_cache.get(account.qrcode_key)):
        return {
            "code": 401,
            "message": "未绑定B站账号",
        }
    password_hash = hashlib.md5(account.password.encode()).hexdigest()
    await cursor.execute("SELECT uid FROM bwdap_users WHERE username = %s", [account.username])
    uid = await cursor.fetchone()
    if uid:
        return {
            "code": 409,
            "message": "用户已存在"
        }
    await cursor.execute(
        "INSERT INTO bilibili.bwdap_users (username, password, cookies) VALUES (%s, %s, %s)",
        [account.username, password_hash, cache_cookie])
    await cursor.execute("SELECT uid FROM bwdap_users WHERE username = %s", [account.username])
    uid = await cursor.fetchone()
    return {
        "code": 200,
        "uid": uid["uid"],
        "cookies": cache_cookie,
    }


@router.post("/forget")
async def forget(account: Account, cursor=Depends(get_async_db_cursor)):
    password_hash = hashlib.md5(account.password.encode()).hexdigest()
    if not account.qrcode_key or account.qrcode_key == "":
        return {
            "code": 401,
            "message": "用户未绑定"
        }

    cookie = code_cache.get(account.qrcode_key)
    if not cookie:
        return {
            "code": 401,
            "message": "绑定超时"
        }

    await cursor.execute(
        "SELECT uid FROM bilibili.bwdap_users WHERE username = %s",
        [account.username]
    )
    res = await cursor.fetchone()
    if not res:
        return {
            "code": 404,
            "message": "用户不存在"
        }

    await cursor.execute(
        "UPDATE bilibili.bwdap_users SET cookies = %s, password = %s where username = %s",
        [cookie, password_hash, account.username]
    )

    return {
        "code": 200,
        "message": "success"
    }


async def check_token(token: Annotated[str | None, Header()]):
    ok = await ApiSession.check_cookie(token)
    if not ok:
        raise CookieError


@router.get("/check")
async def check(_dependencies=Depends(check_token)):
    return {"code": 200}
